package cz.muni.fi.pb138.gscholarinfo.classes;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;

public class Author {

    private String name;
    private String googleId;
    private Integer hIndex;
    private AuthorPublications authorPublications;

    public String getGoogleId() {
        return this.googleId;
    }

    public void setGoogleId(String googleId) {
        this.googleId = googleId;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    private void loadPublications() throws IOException {
        //try {
            this.authorPublications = GSUtils.searchAuthorPublications(this);
        /*} catch (IOException ex) {
            Logger.getLogger(Author.class.getName()).log(Level.SEVERE, null, ex);
        }*/
    }

    /**
     * Vypocita hIndex autora
     */
    public void checkHIndex() throws IOException {
        int hIndex = 0;
        loadPublications();
        if (authorPublications==null) {     //pokud autor nema publikace, je hIndex 0
            this.hIndex=0;
            return;
        }
        List<Publication> publicationsList = this.authorPublications.getPublications();  //nacte do listu vsechny publikace autora
        List<Integer> citedList = new LinkedList<Integer>(); //slouzi k zaznamu poctu citaci jednotlivych publikaci

        for (Publication publication : publicationsList) {   //nacte pocty citaci jednotlivych publikaci
            System.out.println("\n PUBLIKACE " + publication);
            citedList.add(numberOfCitations(publication)); 
        }
        Collections.sort(citedList, new DescentIntegerComparator()); //serazeni sestupne
        System.out.println("\n\nPOCTY CITACI PUBLIKACI: " + citedList);

        for (int index = 0; index < publicationsList.size(); index++) {   //vypocet hIndexu
            if (citedList.get(index) >= index + 1) {
                hIndex = index + 1;
            } else {
                break;
            }
        }

        this.hIndex = new Integer(hIndex);
System.out.println("\n\nHINDEX AUTORA JE: " + hIndex);
    }

    /**
     * @param pub Publikace pro kterou chceme zjistit pocet citaci
     * @return Pocet citaci daneho dila (vyjma citaci od autoru dila)
     */
    private Integer numberOfCitations(Publication pub) throws IOException {
        System.out.println("    VYPOCET CITACI PUBLIKACE " + pub.getTitle());
        Integer cited = new Integer(0);
        boolean fakeCited = false;
        PublicationCitations publicationCitations;
                
        //Vieme, ze publikacia nebola citovana, ak nema GID, citedTimes == 0 (Michal)
        if (pub.getCitedTimes() != 0)
            publicationCitations = GSUtils.searchPublicationCitations(pub, 135);
        else { // publikace nebyla citovana
            System.out.println("      Publikace nebyla citovana");
            return cited;
        }
        List<Publication> publicationCitationsList;   //publikace, ktere cituji pub
        publicationCitationsList = publicationCitations.getCitedIn();
        
        List<String> authorsOfPub = pub.getAuthors();  //autori publikace, pro kterou zjistujeme citace
        for (Publication actualPublication : publicationCitationsList) {
            for (String actualAuthor : authorsOfPub) {         
                if (actualPublication.getAuthors().contains(actualAuthor)) {
                    System.out.println("------------VYRAZUJE SE " +actualPublication.getTitle()+ ", shodny autor " + actualAuthor);
                    fakeCited = true; // citace se nebude pocitat, protoze se shoduji autori
                    break;
                }
            }
            if (!fakeCited) {
                cited++;
            }
            fakeCited = false;
        }
        System.out.println("     PUBLIKACE CITOVANA = " + cited);
        return cited;
    }

    /**
     * @return -1 if hindex is unknown. Else authors hIndex
     */
    public int getHIndex() {
        if (hIndex != null) {
            return hIndex.intValue();
        }
        return -1;
    }
    
    /**
     * 
     * @return null if there is no publications, else return publications
     */
    public AuthorPublications getAuthorPublications() throws IOException {
        loadPublications();
        return this.authorPublications;
    }

    @Override
    public String toString() {
        if (hIndex == null) {
            return name + "; GID = " + googleId + "; H-Index = " + "UNKNOWN";
        }
        return name + "; GID = " + googleId + "; H-Index = " + hIndex;
    }
}



class DescentIntegerComparator implements Comparator {
    
    
    @Override
    public int compare(Object i1, Object i2) {
        return (Integer) i2 - (Integer) i1;
    }
}
